﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.IO;
using Com.Mc.Common.Cameras;
using Com.Mc.Common.Cameras.Common;
using Com.Mc.Common.Base.delegates;
using PluginService.Common.Model;

namespace CameraService
{
    public class CameraManager:IDisposable
    {
        #region 构造函数

        public CameraManager() { }

        #endregion

        #region 变量

        protected static log4net.ILog _log = log4net.LogManager.GetLogger(typeof(CameraManager));

        private List<CameraEntity> _cameraEntitys;

        private Dictionary<string, ICapture> _captureDic=new Dictionary<string,ICapture>();

        private bool _inited = false;

        protected string _camerasJsonFilePath=string.Empty;

        #endregion

        #region 事件

        public event OnReceivedImage OnReceivedImage;

        public event OnCaptureCameraStart OnCaptureCameraStart;

        public event OnSuspendedCamera OnSuspendedCamera;

        public event OnErrorHander OnError;

        public event OnFinishPlaying OnFinishPlaying;

        public event OnCaptureFaileHander OnCaptureFailed;

        #endregion

        #region 公共函数

        public void Init(string configpath)
        {
            InitCamreaCrater(configpath + "Config\\CameraType.xml");
            if (CameraCreater.CameraCreater.Instance.Inited)
            {
                _cameraEntitys = GetCameraEntity(configpath);
                if (_cameraEntitys != null)
                {
                    OnReceiveCameraConfigJson();
                    _inited = true;
                }
            }
            else
            {
                _log.Error("camera.xml 未配置或未找到该文件");
            }

            
        }

        public void Start()
        {
            foreach (var c in _captureDic.Values)
            {
                try
                {
                    c.Start();
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                }
            }
        }

        public void Stop()
        {
            foreach (var c in _captureDic.Values)
            {
                try
                {
                    c.Stop();
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                }
            }
        }

        public void Suspend()
        {
            foreach (var c in _captureDic.Values)
            {
                try
                {
                    c.Suspend();
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                }
            }
        }

        public void Resume()
        {
            foreach (var c in _captureDic.Values)
            {
                try
                {
                    c.Resume();
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                }
            }
        }

        public bool UpdateCameraConfig(string cameraJson)
        {
            bool result = false;
            if (!string.IsNullOrEmpty(_camerasJsonFilePath))
            {
                string fileName = _camerasJsonFilePath + "Config\\Cameras.json";
                string backFileName = _camerasJsonFilePath+"Config\\Cameras_bak.json";
                bool isCreateSuccess = true;

                if (File.Exists(backFileName))
                {
                    try
                    {
                        File.Delete(backFileName);
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex);
                        return result;
                    }
                }

                if (File.Exists(fileName))
                {
                    try
                    {
                        File.Move(fileName, backFileName);
                    }
                    catch (Exception ex){ _log.Error(ex); return result; }

                    try
                    {
                        File.Delete(fileName);
                    }
                    catch (Exception ex){ _log.Error(ex);}
                    FileStream fs=null;
                    try
                    {
                        fs = new FileStream(fileName, FileMode.CreateNew);
                        var data = System.Text.UTF8Encoding.UTF8.GetBytes(cameraJson);
                        fs.Write(data, 0, data.Length);
                        
                    }
                    catch (Exception ex)
                    {
                        isCreateSuccess = false;
                        _log.Error(ex);
                    }
                    finally
                    {
                        if (fs != null)
                        {
                            fs.Flush();
                            fs.Close();
                        }
                        if (!isCreateSuccess)
                        {
                            File.Move(backFileName, fileName);
                        }
                        else
                        {
                            File.Delete(backFileName);
                        }
                    }
                    result = true;
                }
            }
            return result;
        }

        #endregion

        #region 受保护函数

        protected virtual List<CameraEntity> GetCameraEntity(string configpath)
        {
            try
            {
                var result = Com.Mc.Common.Base.JsonFileReader.JsonFileReader<List<CameraEntity>>.GetObject(configpath + "Config\\Cameras.json");
                _camerasJsonFilePath = configpath;
                return result;
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                
            }
            return null;
        }

        protected virtual void OnReceiveCameraConfigJson()
        {
            _captureDic.Clear();

            foreach (var c in _cameraEntitys)
            {
                try
                {
                    var camera = CreateCapture(c);

                    if (camera != null)
                    {
                        _captureDic.Add(c.Id, camera);
                    }
                }
                catch (Exception ex)
                {

                    _log.Error(string.Format("摄像机{0}创建失败", c.Id));
                    _log.Error(ex);
                }

            }
        }

        protected virtual void InitCamreaCrater(string configPath)
        {
            string str = System.Environment.CurrentDirectory;
            try
            {
                CameraCreater.CameraCreater.Instance.Init(configPath);
            }
            catch (Exception ex)
            {
                _log.Error(ex);
            }
            
        }

        protected virtual ICapture CreateCapture(CameraEntity cameraEntity)
        {
            var camera = CameraCreater.CameraCreater.Instance.GetCamera(cameraEntity.TypeId) as ICapture;
            CameraInfor cameraInfo = new CameraInfor();
            cameraInfo.Address = cameraEntity.Address;
            cameraInfo.DeviceId = cameraEntity.Id;
            cameraInfo.DevicePort = (ushort)cameraEntity.Port;
            cameraInfo.IsCreateImage = true;
            cameraInfo.UserName = cameraEntity.UserName;
            cameraInfo.PassWord = cameraEntity.PassWord;
            cameraInfo.ImageHeight = cameraEntity.ImageHeight;
            cameraInfo.ImageWidth = cameraEntity.ImageWidth;
            cameraInfo.IsUseDeviceId = false;
            camera.CameraInfo = cameraInfo;
            camera.Init();
            

            camera.OnCaptureCameraStart += new OnCaptureCameraStart(OnCaptureCameraStartHander);
            camera.OnCaptureFailded += new OnCaptureFaileHander(OnCameraCaptureFaildedHander);
            camera.OnError += new Com.Mc.Common.Base.delegates.OnErrorHander(OnCameraErrorHander);
            camera.OnFinishPlaying += new OnFinishPlaying(OnFinishPlayingHander);
            camera.OnReceivedImage += new OnReceivedImage(OnReceivedImageHander);
            camera.OnSuspendedCamera += new OnSuspendedCamera(OnSuspendedCameraHander);
            return camera;
        }

        protected virtual void OnSuspendedCameraHander()
        {
            if (OnSuspendedCamera != null)
            {
                OnSuspendedCamera();
            }
        }

        protected virtual void OnReceivedImageHander(ICapture capture,CaptureImageData imageData)
        {
            if (OnReceivedImage != null)
            {
                OnReceivedImage(capture,imageData);
            }
        }

        protected virtual void OnFinishPlayingHander(object sender, FinishPlayingReason reason)
        {
            if (OnFinishPlaying!=null)
            {
                OnFinishPlaying(sender, reason);
            }
        }

        protected virtual void OnCameraErrorHander(Com.Mc.Common.Base.EventArgs.LocalErrorEventArgs args)
        {
            if (OnError != null)
            {
                OnError(args);
            }
        }

        protected virtual void OnCameraCaptureFaildedHander(ICapture capture)
        {
            if (OnCaptureFailed != null)
            {
                OnCaptureFailed(capture);
            }
        }

        protected virtual void OnCaptureCameraStartHander()
        {
            if (OnCaptureCameraStart != null)
            {
                OnCaptureCameraStart();
            }
        }

        #endregion

        #region 属性

        public bool Inited
        {
            get { return _inited; }
        }

        public string[] CaptureIds
        {
            get
            {
                List<string> ids = new List<string>();

                foreach (var k in _captureDic)
                {
                    ids.Add(k.Key);
                    
                }
                return ids.ToArray();
            }
        }

        public List<CameraEntity> CameraEntitys
        {
            get { return _cameraEntitys; }
            set { _cameraEntitys = value; }
        }

        #endregion

        #region IDispose

        public void Dispose()
        {
            foreach (var c in _captureDic.Values)
            {
                try
                {
                    c.Stop();
                    c.Dispose();
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                }
            }
        }
        
        #endregion
        
    }
}
